#include <stdio.h>
#include <string.h>
#include "symtab.h"
#include "parser.h"
#include "keywords.h"

#define MAXSYMTBENTRIES 0x10000
int symtab[MAXSYMTBENTRIES][4];
int symtab_nextentry = 1;

#define MAXLEXTAPESIZ   0x100000
char lextape[MAXLEXTAPESIZ];
int lextape_nextentry = 0;

int symtab_insert(char const *symbol, int otype, int dtype,int offset)
{
  symtab[symtab_nextentry][0] = lextape_nextentry;
  symtab[symtab_nextentry][1] = otype;
  symtab[symtab_nextentry][2] = dtype;
  symtab[symtab_nextentry][3] = offset;
  strcpy(lextape + lextape_nextentry,symbol);
  lextape_nextentry += strlen(symbol) + 1;
  return symtab_nextentry++;
}

int symtab_lookup(char const *symbol)
{
  int i;
  for(i=symtab_nextentry-1;i>0; i--){
    if(strcmp(lextape+symtab[i][0],symbol)==0) return i;
  }
  return 0;
}

void symtab_removelocals(){
  int i = symtab_nextentry-2;
  int j = symtab_nextentry-1;
  
  while(symtab[i][1] == PARMTYPE){
    symtab[i][0] = symtab[j][0];
    symtab[i][1] = symtab[j][1];
    symtab[i][2] = symtab[j][2];
    symtab[i][3] = symtab[j][3];
    i--;
    j--;
    symtab_nextentry--;
  }
}

int getNextEntry(){
   return symtab_nextentry;
}

void setNextEntry(int nextEntry){
   symtab_nextentry = nextEntry;
}

int getOffset(int symbol_entry){
  return symtab[symbol_entry][3];
}

void setOffset(int symbol_entry,int offset_value){
   symtab[symbol_entry][3] = offset_value;
}

int getOtype(int symbol_entry){
  return symtab[symbol_entry][1];
}

int getDtype(int symbol_entry){
  return symtab[symbol_entry][2];
}

void setDtype(int symbol_entry,int dtype_value){
   symtab[symbol_entry][2] = dtype_value;
}

void print_symtab(void){
  int i;
  printf("symbol table:\n");
  
  for(i=1;i < symtab_nextentry; i++){
    printf("symbol: %s",(lextape+symtab[i][0]));
    switch(symtab[i][1]){
      case VARTYPE: printf(" - objtype: VAR");
		    break;
      case PROCTYPE: printf(" - objtype: PROCEDURE");
		    break;
      case FUNCTYPE: printf(" - objtype: FUNCTION");
		 break;
      default: printf(" - objtype: PARAMETER");
    }
    switch(symtab[i][2]){
      case INTEGER: printf(" - datatype: INTEGER");
		    break;
      case REAL: printf(" - datatype: REAL");
		 break;
    }
    printf(" - offset: %d\n",symtab[i][3]);
  }
}